using System.Net;
using System.Net.Mail;
using Microsoft.Extensions.Logging;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Services.Notification
{
    /// <summary>
    /// SMTP 邮件提供商实现
    /// 支持标准SMTP协议的邮件服务器，如Gmail、Outlook、QQ邮箱等
    /// </summary>
    public class SmtpEmailProvider : IEmailProvider, IDisposable
    {
        public string Name => "SMTP";
        
        public bool IsConfigured => !string.IsNullOrEmpty(_settings.Host) && 
                                   !string.IsNullOrEmpty(_settings.Username) && 
                                   !string.IsNullOrEmpty(_settings.Password);

        private readonly SmtpSettings _settings;
        private readonly ILogger _logger;
        private SmtpClient? _smtpClient;
        private readonly object _lockObject = new object();

        public SmtpEmailProvider(SmtpSettings settings, ILogger logger)
        {
            _settings = settings ?? throw new ArgumentNullException(nameof(settings));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        }

        /// <summary>
        /// 获取或创建SMTP客户端
        /// </summary>
        private SmtpClient GetSmtpClient()
        {
            if (_smtpClient == null)
            {
                lock (_lockObject)
                {
                    if (_smtpClient == null)
                    {
                        _smtpClient = new SmtpClient(_settings.Host, _settings.Port)
                        {
                            EnableSsl = _settings.EnableSsl,
                            UseDefaultCredentials = false,
                            Credentials = new NetworkCredential(_settings.Username, _settings.Password),
                            Timeout = _settings.TimeoutSeconds * 1000,
                            DeliveryMethod = SmtpDeliveryMethod.Network
                        };
                    }
                }
            }
            return _smtpClient;
        }

        /// <summary>
        /// 发送邮件
        /// </summary>
        public async Task<EmailSendResult> SendAsync(EmailMessage message)
        {
            if (!IsConfigured)
            {
                return new EmailSendResult
                {
                    Success = false,
                    ErrorMessage = "SMTP提供商未正确配置",
                    SentAt = DateTime.UtcNow,
                    Provider = Name
                };
            }

            try
            {
                using var mailMessage = CreateMailMessage(message);
                var client = GetSmtpClient();
                
                var startTime = DateTime.UtcNow;
                await client.SendMailAsync(mailMessage);
                var endTime = DateTime.UtcNow;

                _logger.LogDebug(
                    "SMTP邮件发送成功 - 收件人: {To}, 主题: {Subject}, 耗时: {Duration}ms",
                    message.To, message.Subject, (endTime - startTime).TotalMilliseconds);

                return new EmailSendResult
                {
                    Success = true,
                    MessageId = mailMessage.Headers["Message-ID"],
                    SentAt = endTime,
                    Provider = Name
                };
            }
            catch (SmtpException ex)
            {
                _logger.LogError(ex, "SMTP邮件发送失败 - 收件人: {To}, SMTP错误: {StatusCode}", 
                    message.To, ex.StatusCode);
                
                return new EmailSendResult
                {
                    Success = false,
                    ErrorMessage = $"SMTP错误 ({ex.StatusCode}): {ex.Message}",
                    SentAt = DateTime.UtcNow,
                    Provider = Name
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "SMTP邮件发送异常 - 收件人: {To}", message.To);
                
                return new EmailSendResult
                {
                    Success = false,
                    ErrorMessage = ex.Message,
                    SentAt = DateTime.UtcNow,
                    Provider = Name
                };
            }
        }

        /// <summary>
        /// 测试连接
        /// </summary>
        public async Task<bool> TestConnectionAsync()
        {
            if (!IsConfigured)
            {
                _logger.LogWarning("SMTP提供商未配置，跳过连接测试");
                return false;
            }

            try
            {
                var testMessage = new EmailMessage
                {
                    To = _settings.FromAddress,
                    Subject = "SMTP连接测试",
                    TextBody = "这是一条测试邮件，用于验证SMTP服务配置是否正确。",
                    From = _settings.FromAddress,
                    FromName = _settings.FromName
                };

                using var mailMessage = CreateMailMessage(testMessage);
                var client = GetSmtpClient();
                
                // 只验证连接，不实际发送
                // 某些SMTP服务器不支持NOOP命令，所以这里使用简单的连接测试
                await Task.Run(() =>
                {
                    using var testClient = new SmtpClient(_settings.Host, _settings.Port)
                    {
                        EnableSsl = _settings.EnableSsl,
                        UseDefaultCredentials = false,
                        Credentials = new NetworkCredential(_settings.Username, _settings.Password),
                        Timeout = 10000 // 10秒超时
                    };
                    
                    // 尝试连接但不发送邮件
                    testClient.Send(new MailMessage(_settings.FromAddress, _settings.FromAddress, "Test", "Test"));
                });

                _logger.LogInformation("SMTP连接测试成功 - 服务器: {Host}:{Port}", _settings.Host, _settings.Port);
                return true;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "SMTP连接测试失败 - 服务器: {Host}:{Port}", _settings.Host, _settings.Port);
                return false;
            }
        }

        /// <summary>
        /// 创建邮件消息对象
        /// </summary>
        private MailMessage CreateMailMessage(EmailMessage message)
        {
            var from = !string.IsNullOrEmpty(message.From) ? message.From : _settings.FromAddress;
            var fromName = !string.IsNullOrEmpty(message.FromName) ? message.FromName : _settings.FromName;

            var mailMessage = new MailMessage();

            // 设置发件人
            if (!string.IsNullOrEmpty(fromName))
            {
                mailMessage.From = new MailAddress(from, fromName);
            }
            else
            {
                mailMessage.From = new MailAddress(from);
            }

            // 设置收件人
            if (!string.IsNullOrEmpty(message.ToName))
            {
                mailMessage.To.Add(new MailAddress(message.To, message.ToName));
            }
            else
            {
                mailMessage.To.Add(new MailAddress(message.To));
            }

            // 设置主题和内容
            mailMessage.Subject = message.Subject;
            mailMessage.SubjectEncoding = System.Text.Encoding.UTF8;
            
            // 设置邮件内容
            if (!string.IsNullOrEmpty(message.HtmlBody))
            {
                var htmlView = AlternateView.CreateAlternateViewFromString(
                    message.HtmlBody, 
                    System.Text.Encoding.UTF8, 
                    "text/html");
                mailMessage.AlternateViews.Add(htmlView);
                mailMessage.IsBodyHtml = true;
            }

            if (!string.IsNullOrEmpty(message.TextBody))
            {
                if (string.IsNullOrEmpty(message.HtmlBody))
                {
                    // 只有文本内容
                    mailMessage.Body = message.TextBody;
                    mailMessage.BodyEncoding = System.Text.Encoding.UTF8;
                    mailMessage.IsBodyHtml = false;
                }
                else
                {
                    // 添加纯文本版本
                    var textView = AlternateView.CreateAlternateViewFromString(
                        message.TextBody, 
                        System.Text.Encoding.UTF8, 
                        "text/plain");
                    mailMessage.AlternateViews.Add(textView);
                }
            }

            // 设置优先级
            mailMessage.Priority = message.Priority switch
            {
                2 => MailPriority.High,
                0 => MailPriority.Low,
                _ => MailPriority.Normal
            };

            // 添加附件
            foreach (var attachment in message.Attachments)
            {
                var stream = new MemoryStream(attachment.Content);
                var mailAttachment = new Attachment(stream, attachment.FileName, attachment.ContentType);
                
                if (attachment.IsInline && !string.IsNullOrEmpty(attachment.ContentId))
                {
                    mailAttachment.ContentId = attachment.ContentId;
                    if (mailAttachment.ContentDisposition != null)
                    {
                        mailAttachment.ContentDisposition.Inline = true;
                    }
                }
                
                mailMessage.Attachments.Add(mailAttachment);
            }

            // 添加自定义头信息
            if (message.Headers != null)
            {
                foreach (var header in message.Headers)
                {
                    mailMessage.Headers.Add(header.Key, header.Value);
                }
            }

            // 生成Message-ID
            if (!mailMessage.Headers.AllKeys.Contains("Message-ID"))
            {
                var messageId = $"<{Guid.NewGuid()}@{_settings.Host}>";
                mailMessage.Headers.Add("Message-ID", messageId);
            }

            return mailMessage;
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            if (_smtpClient != null)
            {
                lock (_lockObject)
                {
                    if (_smtpClient != null)
                    {
                        _smtpClient.Dispose();
                        _smtpClient = null;
                    }
                }
            }
        }
    }
}
